#include <MainWindow.h>
#include <Game/GameFSM.h>

namespace pp
{
    MainWindow::MainWindow()
        : mBackgroudColor(ne::Color::BLACK)
    {
        mpEngine = ne::Engine::GetSingletonPtr();
        mpScreen = mpEngine->getScreen();
        mpRenderSystem = mpEngine->getRenderSystem();

        mpCamera = new ne::Camera();
        mpCamera->setProjectionType(ne::PT_ORTHOGRAPHIC);
        mpCamera->setPosition(ne::Vector3::UNIT_Z);
        mpViewport = new ne::Viewport(mpCamera);

        mpScreen->addListener(this);

        mpTimer = new ne::Timer();
        mpTimer->reset();
        mFrameNum = 0;
        mFrameTime = 0;
        mFPS = 0;
    }

    bool MainWindow::tick()
    {
        double interval = mpTimer->getIntervalSeconds();
        mFrameTime += interval;
        ++mFrameNum;
        if (mFrameTime > 1.0f)
        {
            mFPS = mFrameNum / mFrameTime;
            mFrameNum = 0;
            mFrameTime = 0;
        }

        return true;
    }

    bool MainWindow::render()
    {
        mpRenderSystem->setClearColor(mBackgroudColor);
        mpRenderSystem->clear(true, true);

        const ne::Matrix4 pM = mpCamera->getProjectionMatrix();
        const ne::Matrix4 vM = mpCamera->getViewMatrix();
        mpRenderSystem->setProjectionMatrix(pM);
        mpRenderSystem->setViewMatrix(vM);

        char fpsString[32];
	    sprintf(fpsString, "FPS : %.3lf", mFPS);
        mpEngine->getFont()->renderText2D(fpsString, ne::Vector3(500.0f, 300.0f, 0.0f), 100, 24, ne::Color(1.0f, 0.0f, 0.0f, 1.0f));

        return true;
    }

    void MainWindow::onResolutionChange(const uint32_t width, const uint32_t height)
    {
        mpViewport->setPosition(0, 0);
        mpViewport->resize(width, height);
        mpRenderSystem->setViewport(mpViewport);
    }

    void MainWindow::onFullScreenChange(const bool b)
    {
    }

    MainWindow::~MainWindow()
    {
        delete mpTimer;
        mpScreen->removeListener(this);
        delete mpViewport;
        delete mpCamera;
    }

    MainWindow& MainWindow::GetSingleton()
    {
        assert(mpInstance);
        return *mpInstance;
    }

    MainWindow* MainWindow::GetSingletonPtr()
    {
        return mpInstance;
    }
}
